<?php
/*
Plugin Name: OneClick Installer
Plugin URI: http://anirudhsanjeev.org/projects/oneclick/
Description: Installs any plugin or theme without having to upload them manually via ftp. Can also delete theme and plugin folders.
Version: 0.9.8
Author: Anirudh Sanjeev
Author URI: http://anirudhsanjeev.org/
*/
/*  Copyright YEAR  PLUGIN_AUTHOR_NAME  (email : PLUGIN AUTHOR EMAIL)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
Note to myself:
to update the plugin:
1. change the version in header
2. modify checkforupdate
3. modify the update check text file on the main server

*/


function AddToSubMenu()
{
    add_submenu_page('index.php', 'OneClick Installer', 'OneClick Install', 10,
        __file__, 'RenderPage');
}
add_action('admin_menu', 'AddToSubMenu');

function is__writable($path)
{
    //will work in despite of Windows ACLs bug
    //NOTE: use a trailing slash for folders!!!
    //see http://bugs.php.net/bug.php?id=27609
    //see http://bugs.php.net/bug.php?id=30931

    if ($path{strlen($path) - 1} == '/') // recursively return a temporary file path

        return is__writable($path . uniqid(mt_rand()) . '.tmp');
    else
        if (is_dir($path))
            return is__writable($path . '/' . uniqid(mt_rand()) . '.tmp');
    // check tmp file for read/write capabilities
    $rm = file_exists($path);
    $f = @fopen($path, 'a');
    if ($f === false)
        return false;
    fclose($f);
    if (!$rm)
        unlink($path);
    return true;
}
function recursive_remove_directory($directory, $empty = false)
{
    if (substr($directory, -1) == '/')
    {
        $directory = substr($directory, 0, -1);
    }
    if (!file_exists($directory) || !is_dir($directory))
    {
        return false;
    }
    elseif (!is_readable($directory))
    {
        return false;
    }
    else
    {
        $handle = opendir($directory);
        while (false !== ($item = readdir($handle)))
        {
            if ($item != '.' && $item != '..')
            {
                $path = $directory . '/' . $item;
                if (is_dir($path))
                {
                    recursive_remove_directory($path);
                }
                else
                {
                    unlink($path);
                }
            }
        }
        closedir($handle);
        if ($empty == false)
        {
            if (!rmdir($directory))
            {
                return false;
            }
        }
        return true;
    }
}
function humansize($size)
{

    $kb = 1024; // Kilobyte
    $mb = 1024 * $kb; // Megabyte
    $gb = 1024 * $mb; // Gigabyte
    $tb = 1024 * $gb; // Terabyte

    if ($size < $kb)
        return $size . "B";
    else
        if ($size < $mb)
            return round($size / $kb, 0) . "KB";
        else
            if ($size < $gb)
                return round($size / $mb, 0) . "MB";
            else
                if ($size < $tb)
                    return round($size / $gb, 0) . "GB";
                else
                    return round($size / $tb, 2) . "TB";
}
function checkdirectories()
{
    //check oneclick folder chmod
    if (is__writable('../wp-content/plugins/oneclick/'))
    {
?>
    <img src="../wp-content/plugins/oneclick/happy.png" />Oneclick folder is configured correctly.<br />

    <?php
    }
    else
    {
?>
    <img src="../wp-content/plugins/oneclick/sad.png" />Oneclick folder is NOT configured correctly. <a href="http://anirudhsanjeev.org/oneclick/manual.html#chmod">Click here to rectify.</a><br />

    <?php
    }
    if (is__writable('../wp-content/plugins/'))
    { ?>
    <img src="../wp-content/plugins/oneclick/happy.png" />Plugins folder is configured correctly.<br />

    <?php

    }
    else
    { ?>
	    <img src="../wp-content/plugins/oneclick/sad.png" />Plugins folder is NOT configured correctly. <a href="http://anirudhsanjeev.org/oneclick/manual.html#chmod">Click here to rectify.</a><br />

    <?php
    }
    if (is__writable('../wp-content/themes/'))
    {
?>
    <img src="../wp-content/plugins/oneclick/happy.png" />Themes folder is configured correctly.<br />

    <?php
    }
    else
    { ?>
	    <img src="../wp-content/plugins/oneclick/sad.png" />Themes folder is NOT configured correctly. <a href="http://anirudhsanjeev.org/oneclick/manual.html#chmod">Click here to rectify.</a><br />

    <?php
    }
    if (checkForUpdate())
    {
?>
    <img src="../wp-content/plugins/oneclick/happy.png" />You are running the latest version of OneClick<br />

    <?php
    }
    else
    { ?>
	    <img src="../wp-content/plugins/oneclick/sad.png" />An Update is available.<a href="<?php echo
        $_SERVER['PHP_SELF'],
            "?page=oneclick/oneclick.php&installtype=plugin&urlinstall=true&fileurl=http://anirudhsanjeev.org/files/oneclick.zip&update=true"; ?>">Click here to install</a><br />

    <?php
    }
}

function getcontents($filename)
{
    if ($file = @file_get_contents($filename))
    {
    }
    else
    {
        $curl = curl_init($filename);
        curl_setopt($curl, CURLOPT_HEADER, 0); // ignore any headers
        ob_start(); // use output buffering so the contents don't get sent directly to the browser
        curl_exec($curl); // get the file
        curl_close($curl);
        $file = ob_get_contents(); // save the contents of the file into $file
        ob_end_clean(); // turn output buffering back off
    }
    return $file;
}
function ocopen($filename, $mode)
{
    $fp = @fopen($filename, $mode);
    if (!$fp)
    {
        $fp = @popen("curl $filename", "r");
        if (!$fp)
        {
            return false;
        }
    }
    return $fp;
}
function checkForUpdate()
{
    $updatefile = @fopen('http://anirudhsanjeev.org/oneclick/ocupdate.txt', 'r');
    //$updatefile=@fopen('http://localhost/oneclick.txt','r');//this is for my debugging use
    $currentver = '0.9.8';
    if (@fgets($updatefile) == $currentver)
    {
        return true;
    }
    @fclose($updatefile);
    return false;

}
// cURL fallback routine for fclose()
function occlose($fp)
{
    if (!@fclose($fp))
    {
        return @pclose($fp);
    }
    return true;
}
function download($file_source)
{
    $file_target = '../wp-content/plugins/oneclick/temp.zip';
    // Preparations
    /*$file_source = str_replace(' ', '%20', html_entity_decode($file_source)); // fix url format
    echo $file_target;
    // Begin transfer
    if (($rh = fopen($file_source, 'rb')) === FALSE) { return false; } // fopen() handles
    if (($wh = fopen($file_target, 'wb')) === FALSE) { return false; } // error messages.
    while (!feof($rh))
    {
    // unable to write to file, possibly because the harddrive has filled up
    if (fwrite($wh, fread($rh, 1024)) === FALSE) { fclose($rh); fclose($wh); return false; }
    }

    // Finished without errors
    fclose($rh);
    fclose($wh);
    extractPlugin('temp.zip');
    //unlink($file_target);
    unlink($file_target);
    return true;*/
    $file = getcontents($file_source);
    $df = ocopen($file_target, 'w');
    if (!fwrite($df, $file))
    {
    }
    occlose($file_target);
    extractPlugin('temp.zip');
    unlink($file_target);

}
function handleAPI()
{
    if ($_GET["urlinstall"])
    {
        download($_GET["fileurl"], 0);
    }
}
function extractPlugin($uploadedfile)
{
    if (!class_exists('PclZip'))
    {
        require_once ('pclzip.lib.php');
    }
    $archive = new PclZip(sprintf("../wp-content/plugins/oneclick/%s", $uploadedfile));
    if ($_POST["installertype"] == 1)
    {
    	if (($list = $archive->listContent()) == 0)
        {
            die("Error : " . $zip->errorInfo(true));
        }
        $createfolder = false;
        for ($i = 0; $i < sizeof($list); $i++)
        {
            for (reset($list[$i]); $key = key($list[$i]); next($list[$i]))
            {
                //echo "File $i / [$key] = " . $list[$i][$key] . "<br>";
            }
            if (!preg_match('./.', $list[$i]['filename']))
            {
                $createfolder = true;
                break;
            }
        }
        if($createfolder)
        {
        	$append='theme'.rand(0,999).'/';//append the theme name
        }
        else 
    	{
    		$append='';
    	}
        if ($archive->extract(PCLZIP_OPT_PATH, '../wp-content/themes/'.$append) == 0)
        {
            if (function_exists('exec'))
            {
                exec("unzip -d ../wp-content/themes/$append ../wp-content/plugins/oneclick/$uploadedfile");
            }
        }    

    }
    else
    {
        if ($archive->extract(PCLZIP_OPT_PATH, '../wp-content/plugins/') == 0)
        {
            if (function_exists('exec'))
            {
                exec("unzip -d ../wp-content/plugins/ ../wp-content/plugins/oneclick/$uploadedfile");
            }
        }
    }
    if ($_GET['installtype'] === 'theme')
    {
        if (($list = $archive->listContent()) == 0)
        {
            die("Error : " . $zip->errorInfo(true));
        }
        $createfolder = false;
        for ($i = 0; $i < sizeof($list); $i++)
        {
            for (reset($list[$i]); $key = key($list[$i]); next($list[$i]))
            {
                //echo "File $i / [$key] = " . $list[$i][$key] . "<br>";
            }
            if (!preg_match('./.', $list[$i]['filename']))
            {
                $createfolder = true;
                break;
            }
        }
        if($createfolder)
        {
        	$append='theme'.rand(0,999).'/';//append the theme name
        }
        else 
    	{
    		$append='';
    	}
        if ($archive->extract(PCLZIP_OPT_PATH, '../wp-content/themes/'.$append) == 0)
        {
            if (function_exists('exec'))
            {
                exec("unzip -d ../wp-content/themes/$append ../wp-content/plugins/oneclick/$uploadedfile");
            }
        }
    }
    else
        if ($_GET['installtype'] === 'plugin')
        {
            if ($archive->extract(PCLZIP_OPT_PATH, '../wp-content/plugins/') == 0)
            {
                if (function_exists('exec'))
                {
                    exec("unzip -d ../wp-content/plugins/ ../wp-content/plugins/oneclick/$uploadedfile");
                }
            }
        }

?>
  <div class="fade updated" id="message">
	<p>All done. You can go activate your plugin/theme from the Plugin/Theme menus.<?php if ($_GET['update'])
    {
        echo "<br>OneClick has been successfully updated. Please go to your dashboard, and go back to the oneclick page to see the changes";
    } ?>
	<br>
	<?php if($createfolder)
	{
	echo "<br><br>Please note that the theme you uploaded didn't have it's own directory in the zip file. It has been extracted under the directory name '$append'. Don't worry. everything will still work perfectly fine.";
	}
	?>
	</p>
	</div>
    <?php
}
?>
<?php
function RenderPage()
{
    if ($_POST["uploadtype"] === "file")
    {
        if (DIRECTORY_SEPARATOR == '/')
            $absolute_path42 = dirname(__file__) . '/';
        else
            $absolute_path42 = str_replace('\\\\', '/', dirname(__file__)) . '/';
        $uploaddir = $absolute_path42;
        $allowed_ext = "zip";
        $max_size = "5000000";

        // Check Entension
        $extension = pathinfo($_FILES['file']['name']);
        $extension = $extension[extension];
        $allowed_paths = explode(", ", $allowed_ext);
        for ($i = 0; $i < count($allowed_paths); $i++)
        {
            if ($allowed_paths[$i] == "$extension")
            {
                $ok = "1";
            }
        }

        // Check File Size
        if ($ok == "1")
        {
            if ($_FILES['file']['size'] > $max_size)
            {
                print "File size is too big!";
                exit;
            }
        }
        // The Upload Part
        if (is_uploaded_file($_FILES['file']['tmp_name']))
        {
            move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . '/' . $_FILES['file']['name']);
            extractPlugin($_FILES['file']['name']);
            unlink($uploaddir . '/' . $_FILES['file']['name']);
        }
        else
            if ($_POST["contentposted"])
            {
                print 'Something is wrong. The file is unable to upload. Are you sure the plugin, temp and theme directory are chmodded to 0777?';
            }
    }
    else
        if ($_POST["uploadtype"] === "url")
        {
            download($_POST["path"]);
        }

?>
<div class="wrap">
<?php
    handleAPI(); ?>
<h2>Install from local zip File</h2>
<form action=<?php echo "\"", $_SERVER['PHP_SELF'],
    "?page=oneclick/oneclick.php"; ?>" method="post" ENCTYPE="multipart/form-data">  <p>File:    <input type="file" name="file" size="30" >    <br />    Type:     <select name="installertype" id="installertype">      <option value="1">Theme</option>      <option value="0">Plugin</option>        </select>    <br />  </p>  <p class="submit">   <input type="hidden" name="uploadtype" value="file" /> <input type="submit" value="GO" style="width:100px; height:30px"></p></form>
<h2>Install from remote zip File</h2>
<form action=<?php echo "\"", $_SERVER['PHP_SELF'],
    "?page=oneclick/oneclick.php"; ?>" method="post" ENCTYPE="multipart/form-data">  <p>URL:    <input type="text" size="30" name="path">    <br />    Type:  <input type="hidden" name="uploadtype" value="url" />   <select name="installertype" id="installertype">      <option value="1">Theme</option>      <option value="0">Plugin</option>        </select>    <br />  </p>  <p class="submit">    <input type="submit" value="GO" style="width:100px; height:30px"></p></form>
<h2>Diagnostics</h2>
<?php checkdirectories(); ?>
<h2>Delete a Plugin Folder/File</h2>
<p>
Delete any plugin folder or file by clicking on the delete button. THE SYSTEM WILL NOT ASK YOU "ARE YOU SURE", so if you click, the directory will be destroyed. So be careful.<br />
<br />
<table class="widefat plugins">
<thead>
  <tr>
 <th>File/Folder Name</th>
<th style="text-align: center">Size</th>
<th style="text-align: center">Delete</th>
  </tr>
  </thead>
<?php

    $path = dirname($_SERVER['SCRIPT_FILENAME']) . '/../wp-content/plugins/';
    $d = dir($path);
    $icon = '';
    $i = 0;
    while (false !== ($entry = $d->read()))
    {
        $i++;
        if (substr($entry, 0, 1) == '.')
            continue;

        // get size
        $size = filesize($path . '/' . $entry);
        $humansize = humansize($size);
        if ($_POST["deleteid"] === $entry) //this file/folder is doomed

        {
            $i++;
            echo dirname($_SERVER['SCRIPT_FILENAME']) . '/../wp-content/plugins/' . $entry;
            if (is_file($path . '/' . $entry))
            {
                unlink(dirname($_SERVER['SCRIPT_FILENAME']) . '/../wp-content/plugins/' . $entry);
            }
            else
            {
                recursive_remove_directory(dirname($_SERVER['SCRIPT_FILENAME']) .
                    '/../wp-content/plugins/' . $entry);

            }
        }
        else
        {
?>

<tr <?php if ($i % 2)
            {
                echo "class=\"alternate\"";
            } ?>>
    <td><?php echo $entry; ?></td>
    <td>(<?php echo $humansize; ?>)</td>
    <td><form action="<?php echo "\"", $_SERVER['PHP_SELF'],
            "?page=oneclick.php"; ?>" method="post">
    <input type="hidden" value="<?php echo $entry; ?>" name="deleteid" />
<center><p class="submit"><input type="submit" value="DELETE!!!" style="width:140px;" /></p></center>     
    </form>
    </td>
  </tr>
	<?php
        }
    }

    $d->close();

?>
</table><br />
<br />

</p>
<h2>Delete a Theme Folder/File</h2>
<p>
Delete any theme folder or file by clicking on the delete button. THE SYSTEM WILL NOT ASK YOU "ARE YOU SURE", so if you click, the directory will be destroyed. So be careful.<br />

<table class="widefat plugins">
<thead>
  <tr>
 <th>File/Folder Name</th>
<th style="text-align: center">Size</th>
<th style="text-align: center">Delete</th>
  </tr>
  </thead>
<?php
    $path = dirname($_SERVER['SCRIPT_FILENAME']) . '/../wp-content/themes/';
    $d = dir($path);
    $icon = '';
    $i = 0;
    while (false !== ($entry = $d->read()))
    {
        $i++;
        if (substr($entry, 0, 1) == '.')
            continue;

        // get size
        $size = filesize($path . '/' . $entry);
        $humansize = humansize($size);
        if ($_POST["deleteid"] === $entry) //this file/folder is doomed

        {
            $i++;
            if (is_file($path . '/' . $entry))
            {
                unlink(dirname($_SERVER['SCRIPT_FILENAME']) . '/../wp-content/themes/' . $entry);
            }
            else
            {
                recursive_remove_directory(dirname($_SERVER['SCRIPT_FILENAME']) .
                    '/../wp-content/themes/' . $entry);
            }
        }
        else
        {
?>

<tr <?php if ($i % 2)
            {
                echo "class=\"alternate\"";
            } ?>>
    <td><?php echo $entry; ?></td>
    <td>(<?php echo $humansize; ?>)</td>
    <td><form action="<?php echo "\"", $_SERVER['PHP_SELF'],
            "?page=oneclick.php"; ?>" method="post">
    <input type="hidden" value="<?php echo $entry; ?>" name="deleteid" />
    <center><p class="submit"><input type="submit" value="DELETE!!!" style="width:140px;" /></p></center>    
    </form>
    </td>
  </tr>
	<?php
        }
    }

    $d->close();

?><br />

</p>
</table>
<br>
<center>
    <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
      <input type="hidden" name="cmd" value="_xclick">
      <input type="hidden" name="business" value="prototype.angel@gmail.com">
      <input type="hidden" name="amount" value="3.00">
      <input type="hidden" name="no_shipping" value="0">
      <input type="hidden" name="no_note" value="1">
      <input type="hidden" name="currency_code" value="USD">
      <input type="hidden" name="tax" value="0">
      <input type="hidden" name="lc" value="IN">
      <input type="hidden" name="bn" value="PP-DonationsBF">
      <input type="image" 

src="https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" 

border="0" name="submit" alt="Make payments with PayPal - it's fast, 

free and secure!">
      <img alt="" border="0" 

src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" 

height="1">
    </form>
    <form action="https://www.paypal.com/cgi-bin/webscr" 

method="post">
      <input type="hidden" name="cmd" value="_xclick">
      <input type="hidden" name="business" value="prototype.angel@gmail.com">
      <input type="hidden" name="amount" value="3.00">
      <input type="hidden" name="no_shipping" value="0">
      <input type="hidden" name="no_note" value="1">
      <input type="hidden" name="currency_code" value="USD">
      <input type="hidden" name="tax" value="0">
      <input type="hidden" name="lc" value="IN">
      <input type="hidden" name="bn" value="PP-DonationsBF">
      <input type="image" 

src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" 

name="submit" alt="Make payments with PayPal - it's fast, free and 

secure!">
      <img alt="" border="0" 

src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" 

height="1">
    </form>
  </center>
<h2>Tools</h2>

OneClick URL for the firefox Extension: <br><blockquote><?php echo get_option('siteurl'),
    "/wp-admin/index.php?page=oneclick/oneclick.php"; ?></blockquote>
Enter this URL as the "OneClick URL" in Tools/Addons/OneClick Installer/Options in firefox.
<br><br>
OneClick Purgatory Module (Bookmark this for future use): <a href="<?php echo
    get_option('siteurl'), "/wp-content/plugins/oneclick/purgatory.php"; ?>"><?php echo
    get_option('siteurl'), "/wp-content/plugins/oneclick/purgatory.php"; ?></a>
<h2>Credits</h2>
OneClick is written by <a href="http://anirudhsanjeev.org/about/">Anirudh Sanjeev</a>. It is powered by the PCLzip library, php, wordpress, and non-stop <a href="http://www.last.fm/user/prototypeangel/charts/?charttype=weekly&subtype=artist&range=135">amon amarth</a>.
</div>
<?php
} ?>